package com.wangsd.web.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.wangsd.common.enums.ButtonType;
import com.wangsd.web.sys.entity.SysButton;
import com.wangsd.web.sys.entity.SysMenu;
import com.wangsd.web.sys.entity.SysPermission;
import com.wangsd.web.sys.mapper.SysMenuMapper;
import com.wangsd.web.sys.service.SysButtonService;
import com.wangsd.web.sys.service.SysMenuService;
import com.wangsd.web.sys.service.SysPermissionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author generator
 * @since 2019-09-02
 */
@Service
public class SysMenuServiceImpl extends ServiceImpl<SysMenuMapper, SysMenu> implements SysMenuService {

    @Autowired
    SysMenuMapper sysMenuMapper;

    @Autowired
    SysButtonService sysButtonService;

    @Autowired
    private SysPermissionService sysPermissionService;

    @Override
    public List<SysMenu> selectByNull() {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNull("pid");
        queryWrapper.eq("deleted",0);
        return sysMenuMapper.selectList(queryWrapper);
    }

    @Override
    public IPage<SysMenu> selectList(Integer pageNum, Integer pageSize) {
        /*所有父菜单*/
        Page<SysMenu> page = new Page<>(pageNum, pageSize);
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.isNull("pid");
        queryWrapper.eq("deleted",0);
        IPage<SysMenu> sysMenuIPage = sysMenuMapper.selectPage(page, queryWrapper);
        List<SysMenu> parent = sysMenuIPage.getRecords();
        this.selectMenu(parent);
        return sysMenuIPage;
    }

    @Override
    public List<SysMenu> selectAll() {
        List<SysMenu> sysMenus = selectByNull();
        this.selectMenu(sysMenus);
        return sysMenus;
    }

    @Override
    @Transactional
    public int delete(Long id) {
        sysButtonService.remove(new QueryWrapper<SysButton>().eq("menu_id", id));
        sysMenuMapper.delete(new QueryWrapper<SysMenu>().eq("pid", id));
        sysMenuMapper.deleteById(id);
        return 1;
    }

    @Override
    @Transactional
    public int addOrUpdate(SysMenu sysMenu) {
        if (sysMenu.getId() != null) {
            sysButtonService.remove(new QueryWrapper<SysButton>().eq("menu_id", sysMenu.getId()));
            sysMenuMapper.updateById(sysMenu);
        } else {
            sysMenuMapper.insert(sysMenu);
        }

        if (sysMenu.getActions() != null) {
            List<SysButton> buttonList = new ArrayList<>();
            for (String item : sysMenu.getActions()) {
                SysButton button = new SysButton();
                button.setMenuId(sysMenu.getId());
                button.setAction(item);
                button.setName(ButtonType.getValueByCode(item));
                buttonList.add(button);
            }
            sysButtonService.saveBatch(buttonList);
        }
        return 1;
    }

    @Override
    public List<SysMenu> selectByRoleId(Long roleId) {
        List<SysMenu> list = sysMenuMapper.selectByRoleId(roleId);
        List<SysPermission> sysPermissions = sysPermissionService.selectByRoleId(roleId);

        Map<Long, List<SysPermission>> permissionMap = null;
        if (sysPermissions != null) {
            permissionMap = sysPermissions.stream().collect(Collectors.groupingBy(SysPermission::getMenuId));
        }

        if (list != null) {
            for (SysMenu sysMenu : list) {
                if (permissionMap != null) {
                    List<SysPermission> permissionVoList = permissionMap.get(sysMenu.getId());
                    if (permissionVoList != null) {
                        List<String> actions = permissionVoList.stream().map(SysPermission::getAccessSign).collect(Collectors.toList());
                        sysMenu.setActions(actions);
                    }
                }
            }
        }
        return list;
    }

    @Override
    @Transactional
    public int updateOther(Long id, String name, String value) {
        return sysMenuMapper.updateOther(id, name, value);
    }

    @Override
    public List<SysMenu> selectByAdmin() {
        QueryWrapper<SysMenu> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("deleted",0);
        List<SysMenu> list = sysMenuMapper.selectList(queryWrapper);
        List<SysButton> buttonList = sysButtonService.list();
        if (buttonList != null) {
            Map<Long, List<SysButton>> buttonMap = buttonList.stream().collect(Collectors.groupingBy(SysButton::getMenuId));
            for (SysMenu item : list) {
                List<SysButton> sysButtonList = buttonMap.get(item.getId());
                if (sysButtonList != null) {
                    List<String> actions = sysButtonList.stream().map(SysButton::getAction).collect(Collectors.toList());
                    item.setActions(actions);
                }
                item.setButtonList(sysButtonList);
            }
        }
        return list;
    }


    private void selectMenu(List<SysMenu> parent) {
        /*所有子菜单*/
        List<SysMenu> childList = sysMenuMapper.selectList(new QueryWrapper<SysMenu>().isNotNull("pid").orderByDesc("sort").eq("deleted",0));
        Map<Long, List<SysMenu>> childMap = childList.stream().collect(Collectors.groupingBy(SysMenu::getPid));

        /*查询所有的按钮*/
        List<SysButton> sysButtonList = sysButtonService.list();
        Map<Long, List<SysButton>> buttonMap = sysButtonList.stream().collect(Collectors.groupingBy(SysButton::getMenuId));

        for (SysMenu sysMenu : parent) {
            /*取出父菜单下的所有子菜单*/
            List<SysMenu> child = childMap.get(sysMenu.getId());
            List<SysMenu> childMenuList = new ArrayList<>();
            if (child == null) {
                continue;
            }
            for (SysMenu menu : child) {
                /*取出子菜单所对应的按钮*/
                List<SysButton> buttonList = buttonMap.get(menu.getId());
                //放按钮权限集
                if (buttonList != null) {
                    List<String> actions = buttonList.stream().map(SysButton::getAction).collect(Collectors.toList());
                    menu.setActions(actions);
                    menu.setButtonList(buttonList);
                } else {
                    menu.setActions(new ArrayList<>());
                    menu.setButtonList(new ArrayList<>());
                }
                childMenuList.add(menu);
            }
            sysMenu.setChildren(childMenuList);
        }
    }
}
